// 单例模式
// 发布订阅
// 策略模式（https://blog.csdn.net/chaoPerson/article/details/135594904）
// reactivty （响应）
class Storage {
    instance = null;  //  单例模式
    static getInstance() {
        if (!instance) {
            instance = new Storage();
        }
        return instance;
    }
    setItem = (key, value) => localStorage.setItem(key, value);
    getItem = key => localStorage.getItem(key)
}




class EventEmitter {
    constructor() {
        this.events = {}
    }
    on(event, callback) {
        this.events[event].push(callback)
    }
    emit(event, ...args) {
        this.events[event].forEach(fn => fn(...args))
    }
    off(event, callback) {
        this.events[event].filter(fn => fn !== callback)  // 注意
    }
    once(event, callback) {
        function wrapFn(...args) {
            this.off(event, wrapFn)
            callback.call(this, ...args)
        }
        this.on(evnet, wrapFn)
    }
}



const describeMapArrary = [
    [
        (name) => name === 'teacher', // 判断条件
        () => {
          // 业务逻辑处理...
          console.log('teacher',"我是学校的老师") // 执行函数
        }
    ],
    [
        (name) => name === 'chef', 
        () => {
           // 业务逻辑处理...
          console.log('chef',"我是酒店的大厨")
        }
    ],
    [
        (name) => name === 'soldier', 
        () => {
          // 业务逻辑处理...
          console.log('soldier',"我是保家卫国的军人")
        }
    ],
    [
        (name) => name === 'driver', 
        () => {
          // 业务逻辑处理...
          console.log('driver',"我是滴滴司机");
          return 'driver 我是driver场景的返回值'; // 有返回值场景
        }
    ],
];
    
function getDescribeName(name) {
    // 获取符合条件的子数组
    const getDescribe = describeMapArrary.find((item) => item[0](name));
    // 子数组存在则运行子数组中的第二个元素（执行函数）
    return getDescribe ? getDescribe[1]() : console.log('default',"没找到你需要的职位描述！");
}
getDescribeName('soldier'); // 查询map中存在的条件
console.log(getDescribeName('driver')); // 查询map中存在的条件并返回函数处理值
getDescribeName('fuchaoyang'); // 查询map中不存在的条件



let effectfunc = null;
class Dep {
    constructor(){
        this.list = []
    }
    on(){
        if(!effectfunc) return;
        this.list.push(effectfunc)
    }
    emit(){
        this.list.forEach(effectfunc => effectfunc())
    }
}

let targetMap = new Map();
function getDep(target, key){
 
    let depMap = targetMap.get(target)
    if(!depMap){
        depMap = new Map()
        targetMap.set(target, depMap)
    }

    let dep = depMap.get(key)
    if(!dep){
        dep = new Dep()
        depMap.set(key, dep)
    }

    return dep
}

function reactivty(target){
    return new Proxy(target, {
        get(target, key, reciver){
            let dep = getDep(target, key)
            dep.on()
            return Reflect.get(target, key, reciver)
        },
        set(target, key, val, reciver){
            let dep = getDep(target, key)
            let result = Reflect.set(target, key, val, reciver)
            dep.emit()
            return result
        }
    })
}

function effect(effect){
    effectfunc = effect;
    effectfunc();
    effectfunc = null
}

// 测试
let obj = reactivty({count: 0})
effect(() => {
    console.log(obj.count)
})
obj.count++;